package com.ttg.common.utils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

/**
 * @author ZQ
 * @version 1.0
 * @Description AES/CBC/ECB
 * @date 2020/12/10 15:19
 */
public class AesUtil {

    private static final String CIPHER_ALGORITHM_CBC = "AES/CBC/PKCS5PADDING";

    private static final String CIPHER_ALGORITHM_ECB = "AES/ECB/PKCS5Padding";

    private static final String KEY_ALGORITHM = "AES";

    /**
     * CBC模式 加密 byte2hex
     * @param key 密钥
     * @param initVector 偏移向量
     * @param data 待加密数据
     */
    public static String encrypt(String key,String initVector,String data) throws Exception{
        IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(StandardCharsets.UTF_8));
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), KEY_ALGORITHM);

        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

        byte[] encrypted = cipher.doFinal(data.getBytes());
        return BasicUtils.byte2hex(encrypted);
    }

    /**
     * CBC模式 解密 byte2hex
     * @param key 密钥
     * @param initVector 偏移向量
     * @param encrypted 加密数据
     */
    public static String decrypt(String key,String initVector,String encrypted) throws Exception{
        IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(StandardCharsets.UTF_8));
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), KEY_ALGORITHM);

        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
        byte[] original = cipher.doFinal(BasicUtils.hex2byte(encrypted));

        return new String(original);
    }

    /**
     * AES + ECB加密 + byte2hex
     */
    public  static String encrypt(String encryptStr, byte[] aesKey) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(aesKey, KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_ECB);
        cipher.init(1, skeySpec);
        byte[] encrypted = cipher.doFinal(encryptStr.getBytes(StandardCharsets.UTF_8));
        return BasicUtils.byte2hex(encrypted);
    }

    /**
     * AES + ECB 解密 + hex2byte
     */
    public static String decrypt(String descyptStr, byte[] aesKey) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(aesKey, KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_ECB);
        cipher.init(2, skeySpec);
        byte[] encrypted = BasicUtils.hex2byte(descyptStr);
        byte[] original = cipher.doFinal(encrypted);
        return new String(original);
    }

}
